\documentclass[12pt,titlepage]{article}

\usepackage{
  color
  ,float
  ,fullpage
  ,setspace
  ,graphicx
,multirow
,mathrsfs
}
\floatstyle{ruled}
\newfloat{mainClass}{thp}{lop}
\floatname{mainClass}{Main Class}

\newfloat{fileFinder}{thp}{lop}
\floatname{fileFinder}{File Finder}

\newfloat{shareServer}{thp}{lop}
\floatname{shareServer}{Share Server}

\newfloat{findGroup}{thp}{lop}
\floatname{findGroup}{Find Group}


\author{Zacharias Thompson\\ Daniel Garcia}

\title{P2P Filesharing using JXTA}

\date{\today}

\begin{document}
\thispagestyle{empty}
\maketitle
%\newpage
\thispagestyle{empty}
\tableofcontents
\thispagestyle{empty}
\newpage


\doublespacing

\section{Problem Statement} \label{sec:intro} \setcounter{page}{1}
The goal of our project was to implement a file sharing system using
JXTA. This includes connecting peers without knowing any prior
information as well as finding and downloading available files on the
system. The project was going to be created so that a user on the
system could specify what kind of a file they were looking for, along
with a search string. After the basics were to be implemented the long
term goal was to add security and private group functionality. This
would enable users to join the world file sharing network, while having
a group of users that could only see each others items if they were
allowed to join their exclusive group.

\section{Current Status}
Currently the file sharing application has a GUI with a decent amount
of features. This GUI is not currently connected to the JXTA
application because all time available was spent dedicated to
attempting to get JXTA working correctly. One peer should be started
as a rendezvous node, which will create and publish the peer group
advertisement. Once this node has been created and group
advertisements are available other peers can attempt to join the
network. These peers should be started with the option to start as a
rendezvous node set to no. This is done by entering a n when the
application asks the user for input. After a peer has been started as
an edge node it will start the JXTA network and start a peer group
discovery service. This service looks for local advertisements; if no
local advertisements are available the getRemoteAdvertisements()
method is called to search the network for a peer group
advertisement. If no group advertisement is found, the current code
has the edge node sitting and waiting to try and find a group. If no
group can be found nothing else can happen anyways. If a group is
found and joined the application then can share files.

Currently if the user clicks the share files button, a series of
output pipes are created for everything in the share directory, as
well as pipe advertisements for each item. Another user can hit the
search button to attempt to find pipe advertisements that represent
files available. The application then tries to create input pipes for
any pipe advertisements that it finds and download them to a specified
directory. This could be changed to fill a list box in the GUI with
files (represented by pipe advertisements), and then let the user
choose specifically which files to download. This was not implemented
this way because currently the pipes are created but the pipe events
are not being created. When the file sharing application finds a
remote file advertisement an input pipe is created and then it waits
for a message, which is not being sent. The node that created an
output pipe with a specified ID should see that input pipe and send
the message when it does.
\section{JXTA File sharing}

The current application is not as far along as was initially planned
for the amount of time that was available. The difficulties of JXTA
proved to be more challenging that initial considerations led us to
believe. The time that was spent working on the application seemed to
be quite a bit of debugging code to figure out what was currently not
working. 

An example of a difficult part to get working was connecting peers
together using a rendezvous node and edge node. It was found that the
ip addresses that JXTA was outputting were correct. At some point the
peers seemed to be reliably connecting and able to find the
advertisements that were being published. Having established
connectivity testing was done to see how far along the application was
getting in sending the files between peers. This is when we found that
the pipes were being created but the messages were not being
sent. After spending approximately four hours debugging the pipes, we
called it a day and decided to meet the next day to continue. If the
peers were connecting and pipes were being created, all that was left
was to get them to download files. Coming back the next day, the same
code was not working in the same way. The peers were no longer
connecting, therefore the applications was never getting to the point
where the pipes could be created.

Time was spent attempting to find the reason why the peers could no
longer see each other. It seemed that edge nodes could no longer find
the advertisements being published by the rendezvous peer. In order to
try and solve this problem, we went back multiple revisions and did
not find that any of them could connect peers together.

The next step that was taken to solve this problem was commenting out
certain part of the source code. In the main logic, after connecting
to peers the application attempts to start the file share system, this
was commented out, so that essentially the only action that was being
taken was the logic that connected peers together. The JXTA
configuration directories were also deleted to ensure a fresh
start. The first time the application was run the edge node peer
successfully found and connected to the rendezvous node. The code was
then uncommented on one peer and run again. This resulted in the peers
not being able to find each other. After trying multiple combinations
to no avail, the code was changed back to the configuration in which
it worked a half hour or so before. When the application was run, the
peers would not connect to each other.

The code that was used was based on concepts from the JXTA programmers
guide, and from the examples inside. Another source that was used was
a document called ``Mastering JXTA.'' The problem that occurred was
that the example code was either very old, and using deprecated
methods, or was not using JXTA how it seemed it should be being
used. The example files for pipes does not look for advertisements, it
has a hard coded advertisement that the client uses to create one
pipe, and the server uses that same method to get the pipe
advertisement to create the pipe on the opposite end. In the file
sharing application we attempted to use JXTA as a true decentralized
peer to peer system where peers don't know where to look for other
peers. We have yet to find an example that works where advertisements
are published and discovered, and operations are successfully
performed on the advertisements.

Before creating the content file sharing system that is currently in
place, we attempted to use the Content Management System (CMS)
class. The CMS class is supposed to make it easier to share and
download files. There are methods that you call for sharing content,
as well as methods that have to be implemented to download the content
that is found when a peer shares something. The CMS class did not seem
to work, the content seemed to be published correctly but other peers
could not download or see the content that was supposed to be
available. After attempting to use the CMS class, and methods, with no
luck the idea was scrapped and a custom content management system
using pipes was implemented.

\section{Source Code} \label{sec:source} Below are samples from main
classes in our project. An svn server containing the project is
located at: http://474p2pfilesharing.googlecode.com/svn/trunk/

\begin{mainClass}
\centering
\begin{verbatim}
    public static void main(String args[]) {
        Main main = new Main();
        
        main.addWindowListener(
                new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        starter = new NetworkStarter();
        starter.startNetwork();
        if(starter.getMode() == 
                net.jxta.platform.NetworkManager.ConfigMode.RENDEZVOUS) {
            rv = new GroupCreator(starter.getNetworkManager());
            sf = new ShareFiles(starter.getNetworkManager(), false);
            GroupAdvertisor gAdv = new GroupAdvertisor
                    (rv.getNetPeerGroup(), rv.getGroupAdvertisement());
            try {
                Thread.sleep(10000);
            } catch(Exception e) {
                // ignored
            }
            gAdv.start();
        } else {
            ed = new FindGroup(starter.getNetworkManager());
            sf = new ShareFiles(starter.getNetworkManager(), true);
        }
    }

\end{verbatim}
\label{main}
\caption{Starting network and filesharing} 
\end{mainClass}


\begin{fileFinder}
\centering
\begin{verbatim}
    public static PipeAdvertisement 
            createFileAdvertisement(File file, PeerGroupID id) {
        String fName = file.getName();
        String delim = "\\.";
        String[] parts = fName.split(delim);
        PipeAdvertisement adv = (PipeAdvertisement)
                AdvertisementFactory.newAdvertisement
                (PipeAdvertisement.getAdvertisementType());
        if(parts.length > 0) {
            adv.setPipeID(IDCreator.createNewPipeID(id));
            adv.setType(PipeService.UnicastType);
            adv.setName(parts[1]);
            adv.setDescription(parts[0]);
        } else {
            System.out.println("Could not create advertisement");
            return null;
        }
        System.out.println("Advertisement created");
        return adv;
    }
\end{verbatim}
\label{finder}
\caption{Creates pipe advertisements for shared files}
\end{fileFinder}

\begin{shareServer}
\centering
\begin{verbatim}
    public void pipeMsgEvent(PipeMsgEvent event) {
        Message msg;
        try {
            msg = event.getMessage();
            if(msg == null) {
                System.out.println("Received an empty message");
                return;
            }
            printMessageStats(msg, true);
        } catch(Exception e) {
            e.printStackTrace();
            return;
        }

        Message.ElementIterator en = msg.getMessageElements();
        if(!en.hasNext()) {
            return;
        }

        MessageElement msgElement =
                msg.getMessageElement(null, ShareClient.MESSAGE_NAME_SPACE);

        if(msgElement.toString() == null) {
            System.out.println("null msg received");
        } else {
            File outFile = new File(file.getName());
            try {
                FileOutputStream fs = new FileOutputStream(outFile);
                ObjectOutputStream oos = new ObjectOutputStream(fs);
                oos.writeObject(msgElement);
            } catch(Exception e) {
                e.printStackTrace();
                System.exit(-1);
            }
            Date date = new Date(System.currentTimeMillis());
            System.out.println("Message received at: " + date.toString());
            System.out.println("Message created at: " + msgElement.toString());
        }
        finish();
    }
\end{verbatim}
\label{share}
\caption{Creates input pipes and handles messages}
\end{shareServer}

\begin{findGroup}
\centering
\begin{verbatim}
    private PeerGroup discoverPeerGroup
            (PeerGroup myNetPeerGroup, PeerGroupID myPeerGroupID) {
        PeerGroup        localPeerGroup;
        DiscoveryService myNetPeerGroupDiscoveryService = null;

        if (myNetPeerGroup != null) {
            myNetPeerGroupDiscoveryService =
                    myNetPeerGroup.getDiscoveryService();
        } else {
            System.out.println("Net Peer Group is null");
            System.exit(-1);
        }

        boolean     isGroupFound                           = false;
        Enumeration localPeerGroupAdvertisementEnumeration = null;

        System.out.println("Trying to find advertisement...");

        while (!isGroupFound) {
            try {
                localPeerGroupAdvertisementEnumeration =
                    myNetPeerGroupDiscoveryService.getLocalAdvertisements
                    (DiscoveryService.GROUP, "GID", myPeerGroupID.toString());
            } catch (java.io.IOException e) {
                System.out.println("Can't discover local adv");
            }

            if (localPeerGroupAdvertisementEnumeration != null) {
                while
                   (localPeerGroupAdvertisementEnumeration.hasMoreElements()) {
                    System.out.println("Found local advertisement");

                    PeerGroupAdvertisement pgAdv = null;

                    pgAdv = (PeerGroupAdvertisement)
                           localPeerGroupAdvertisementEnumeration.nextElement();
                    System.out.println(pgAdv.toString());

                    if (pgAdv.getPeerGroupID().equals(myPeerGroupID)) {
                        myPeerGroupAdvertisement = pgAdv;
                        isGroupFound             = true;

                        break;
                    }
                }
            }

\end{verbatim}
\label{find}
\caption{Searhes for peer advertisements}
\end{findGroup}
\begin{findGroup}
\begin{verbatim}
            myNetPeerGroupDiscoveryService.getRemoteAdvertisements
                    (null, DiscoveryService.GROUP, "GID",
                    myPeerGroupID.toString(), 1, null);

            if (myPeerGroupAdvertisement != null) {
                isGroupFound = true;
            }
        }

        try {
            localPeerGroup = myNetPeerGroup.newGroup(myPeerGroupAdvertisement);
        } catch (net.jxta.exception.PeerGroupException e) {
            e.printStackTrace();

            return null;
        }

        return localPeerGroup;
    }
\end{verbatim}
\caption{Continued section of searching for peer advertisements}
\end{findGroup}


\end{document}
